package com.khadi.testcase.view.process;

import info.clearthought.layout.TableLayout;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

import com.khadi.testcase.util.SessionUtil;
import com.khadi.testcase.view.IWindowContent;
import com.khadi.testcase.view.editor.CustIntegerEditor;
import com.khadi.testcase.view.model.ExecuteTestCaseModel;
import com.khadi.testcase.view.model.HtmlFieldModel;
import com.khadi.testcase.view.model.ProcessModel;
import com.khadi.testcase.view.model.ProcessTableModel;
import com.khadi.testcase.view.model.WorkflowDtlModel;

public class Process implements IWindowContent, ActionListener {

	private static final String EXECUTE_PROCESS = "EXECUTE_PROCESS";
	private ProcessTableModel processTableModel;

	@Override
	public Object getData() {

		return null;
	}

	@Override
	public Component getView() {
		double[] columns = new double[] { -2, -1 };
		double[] rows = new double[] { -2, -2, -2 };

		TableLayout mainFetchLayout = new TableLayout(columns, rows);
		mainFetchLayout.setHGap(5);
		mainFetchLayout.setVGap(5);

		JPanel mainPanel = new JPanel(mainFetchLayout);
		JLabel lbProcess = new JLabel("Process");
		mainPanel.add(lbProcess, "0,0");
		JTextField tfProcess = new JTextField();
		mainPanel.add(tfProcess, "1,0");

		processTableModel = new ProcessTableModel(getColumns());
		JTable tblProcess = new JTable(processTableModel);
		tblProcess.setRowHeight(21);

		CustIntegerEditor custIntegerEditor = new CustIntegerEditor(0, 100);

		tblProcess.getColumnModel().getColumn(1).setCellEditor(
				custIntegerEditor);
		tblProcess.getColumnModel().getColumn(2).setCellEditor(
				custIntegerEditor);
		JScrollPane scrollPane = new JScrollPane(tblProcess);

		mainPanel.add(scrollPane, "0,1,1,1");

		JButton executeProcess = new JButton("Execute Process");
		executeProcess.setActionCommand(EXECUTE_PROCESS);

		executeProcess.addActionListener(this);

		mainPanel.add(executeProcess, "0,2");

		return mainPanel;
	}

	private String[] getColumns() {
		return new String[] { "Work Flow Name", "Waiting Time(Sec)", "Sequence" };
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals(EXECUTE_PROCESS)) {
			doExecuteProcess();
		}
	}

	private void doExecuteProcess() {
		try {
			List<ProcessModel> data = processTableModel.getData();
			Collections.sort(data, new Comparator<ProcessModel>() {
				@Override
				public int compare(ProcessModel o1, ProcessModel o2) {
					return o1.getSequence().compareTo(o2.getSequence());
				}
			});
			Map<String, List<ExecuteTestCaseModel>> executeTestCaseMap = (Map<String, List<ExecuteTestCaseModel>>) SessionUtil
					.getInstance().getSessionMap().get(SessionUtil.WORK_FLOW);

			WebDriver webDriver = null;

			for (ProcessModel processModel : data) {
				String workFlowName = processModel.getWorkFlowName();

				List<ExecuteTestCaseModel> testCaseList = executeTestCaseMap
						.get(workFlowName);

				ExecuteTestCaseModel executeTestCaseModel = testCaseList.get(0);
				if (webDriver == null) {
					String pageUrl = executeTestCaseModel.getWorkFlowModel()
							.getPageUrl();
					webDriver = new FirefoxDriver();
					webDriver.get(pageUrl);
				}
				int milliseconds = processModel.getWaitingTime() == null ? 0
						: (processModel.getWaitingTime() * 1000);

				Thread.sleep(milliseconds);

				doExecuteTestCase(executeTestCaseModel, webDriver);
			}
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	private void doExecuteTestCase(
			final ExecuteTestCaseModel executeTestCaseModel, WebDriver driver) {
		try {

			final List<WorkflowDtlModel> workflowDtlList = executeTestCaseModel
					.getWorkFlowModel().getWorkflowDtlList();

			for (WorkflowDtlModel workflowDtlModel : workflowDtlList) {

				WebElement webElement = getWebElement(workflowDtlModel
						.getHtmlFieldModel(), driver);

				if (workflowDtlModel.getCommandAction().equals("Click")) {

					webElement.click();
				} else {

					webElement.sendKeys(executeTestCaseModel.getTestCaseModel()
							.getPropertyMap().get(
									workflowDtlModel.getDescription()));

				}
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private WebElement getWebElement(HtmlFieldModel htmlFieldModel,
			WebDriver driver) {

		return driver.findElement(By.id(htmlFieldModel.getId()));
	}

	private Map<HtmlFieldModel, WebElement> getWebElementMap(WebDriver driver) {
		Map<HtmlFieldModel, WebElement> webElementMap = new HashMap<HtmlFieldModel, WebElement>();

		List<WebElement> findElements = driver
				.findElements(By.tagName("input"));

		findElements.addAll(driver.findElements(By.tagName("button")));

		findElements.addAll(driver.findElements(By
				.className("z-toolbarbutton-cnt")));

		for (WebElement webElement : findElements) {

			String elementName = webElement.getAttribute("name");

			String elementType = webElement.getAttribute("type");

			String elementId = webElement.getAttribute("id");
			String className = webElement.getAttribute("className");

			String value = webElement.getText();

			HtmlFieldModel htmlFieldModel = new HtmlFieldModel(elementName,
					elementType, elementId, value, className);

			webElementMap.put(htmlFieldModel, webElement);
		}

		return webElementMap;
	}

	@Override
	public void postData(Object object) {

		Map<String, List<ExecuteTestCaseModel>> testCaseMap = (Map<String, List<ExecuteTestCaseModel>>) SessionUtil
				.getInstance().getSessionMap().get(SessionUtil.WORK_FLOW);
		Set<String> keySet = testCaseMap.keySet();

		List<ProcessModel> processModelList = new ArrayList<ProcessModel>();

		for (String workflowName : keySet) {
			ProcessModel model = new ProcessModel();
			model.setWorkFlowName(workflowName);

			processModelList.add(model);
		}

		processTableModel.setData(processModelList);

	}

	@Override
	public void preData(Object object) {
		// TODO Auto-generated method stub

	}

}
